package net.sudot.chess.business.controller.web;

import net.sudot.chess.exception.BusinessException;
import net.sudot.chess.business.controller.AbstractBaseController;
import net.sudot.chess.business.model.SocialUser;
import net.sudot.chess.business.service.PluginService;
import net.sudot.chess.business.service.SocialUserService;
import net.sudot.chess.business.service.UserService;
import net.sudot.chess.plugin.login.LoginPlugin;
import net.sudot.commons.security.SocialUserAuthenticationToken;
import net.sudot.commons.utils.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 社会化用户登录
 *
 * @author tangjialin on 2018-07-09.
 */
@Controller
@RequestMapping("/login/social-user")
public class SocialUserLoginController extends AbstractBaseController {
    @Resource
    private UserService userService;
    @Resource
    private PluginService pluginService;
    @Resource
    private SocialUserService socialUserService;

    /**
     * 社会化登录首页
     *
     * @param loginPluginId 插件ID
     * @param extra         扩展参数
     * @param request       HttpServletRequest
     * @param response      HttpServletResponse
     * @return 返回处理页面
     */
    @RequestMapping({"/{loginPluginId}", "/{loginPluginId}/{extra}"})
    public ModelAndView index(@PathVariable String loginPluginId, @PathVariable(required = false) String extra, HttpServletRequest request, HttpServletResponse response) {
        LoginPlugin loginPlugin = pluginService.getLoginPlugin(loginPluginId);
        if (loginPlugin == null || !loginPlugin.getIsEnabled()) {
            throw new BusinessException("不支持的登录方式");
        }
        return new ModelAndView("redirect:" + loginPlugin.getLoginBeforeUrl(extra));
    }

    /**
     * 登录前处理
     *
     * @param loginPluginId 插件ID
     * @param extra         扩展参数
     * @param request       HttpServletRequest
     * @param response      HttpServletResponse
     * @return 返回处理页面
     */
    @RequestMapping({"/before/{loginPluginId}", "/before/{loginPluginId}/{extra}"})
    public ModelAndView loginBefore(@PathVariable String loginPluginId, @PathVariable(required = false) String extra, HttpServletRequest request, HttpServletResponse response) throws Exception {
        LoginPlugin loginPlugin = pluginService.getLoginPlugin(loginPluginId);
        if (loginPlugin == null || !loginPlugin.getIsEnabled()) {
            throw new BusinessException("不支持的登录方式");
        }

        ModelAndView modelAndView = new ModelAndView();
        loginPlugin.loginBeforeHandle(extra, request, response, modelAndView);
        return modelAndView;
    }

    /**
     * 登录处理
     *
     * @param loginPluginId 插件ID
     * @param extra         扩展参数
     * @param request       HttpServletRequest
     * @param response      HttpServletResponse
     * @return 返回处理页面
     */
    @RequestMapping({"/do/{loginPluginId}", "/do/{loginPluginId}/{extra}"})
    public ModelAndView doLogin(@PathVariable String loginPluginId, @PathVariable(required = false) String extra, HttpServletRequest request, HttpServletResponse response) throws Exception {
        LoginPlugin loginPlugin = pluginService.getLoginPlugin(loginPluginId);
        if (loginPlugin == null || !loginPlugin.getIsEnabled()) {
            throw new BusinessException("不支持的登录方式");
        }

        ModelAndView modelAndView = new ModelAndView();
        loginPlugin.loginHandle(extra, request, response, modelAndView);
        return modelAndView;
    }

    /**
     * 登录后处理
     *
     * @param loginPluginId 插件ID
     * @param extra         扩展参数
     * @param request       HttpServletRequest
     * @param response      HttpServletResponse
     * @return 返回处理页面
     */
    @RequestMapping({"/after/{loginPluginId}", "/after/{loginPluginId}/{extra}"})
    public ModelAndView loginAfter(@PathVariable String loginPluginId, @PathVariable(required = false) String extra, HttpServletRequest request, HttpServletResponse response, ModelMap model, RedirectAttributes redirectAttributes) throws Exception {
        LoginPlugin loginPlugin = pluginService.getLoginPlugin(loginPluginId);
        if (loginPlugin == null || !loginPlugin.getIsEnabled()) {
            throw new BusinessException("不支持的登录方式");
        }

        boolean loginSuccess = loginPlugin.isLoginSuccess(extra, request, response);
        if (!loginSuccess) {
            throw new BusinessException("登录失败");
        }

        String uniqueId = loginPlugin.getUniqueId(request);
        if (StringUtils.isEmpty(uniqueId)) {
            throw new BusinessException("登录失败");
        }
        SocialUser socialUser = socialUserService.findByUniqueId(loginPluginId, uniqueId);
        if (socialUser != null) {
            if (socialUser.getUserId() != null) {
                userService.login(new SocialUserAuthenticationToken(socialUser, false, WebUtils.getRequestFullIp(request)));
            } else {
                redirectAttributes.addAttribute("socialUserId", socialUser.getId());
                redirectAttributes.addAttribute("uniqueId", uniqueId);
            }
        } else {
            socialUser = new SocialUser();
            socialUser.setLoginPluginId(loginPluginId);
            socialUser.setUniqueId(uniqueId);
            socialUser.setUserId(null);
            socialUserService.save(socialUser);
            redirectAttributes.addAttribute("socialUserId", socialUser.getId());
            redirectAttributes.addAttribute("uniqueId", uniqueId);
        }
        ModelAndView modelAndView = new ModelAndView();
        loginPlugin.loginAfterHandle(socialUser, extra, loginSuccess, request, response, modelAndView);
        return modelAndView;
    }

}